package com.dz.scrm.app.config

import android.app.Application
import android.content.Context
import androidx.fragment.app.FragmentManager
import com.dz.scrm.BuildConfig
import com.dz.scrm.mvp.model.api.APP_DOMAIN
import me.jessyan.art.base.delegate.AppLifecycles
import me.jessyan.art.di.module.GlobalConfigModule
import me.jessyan.art.http.imageloader.glide.GlideImageLoaderStrategy
import me.jessyan.art.http.log.RequestInterceptor
import me.jessyan.art.integration.ConfigModule
import me.jessyan.progressmanager.ProgressManager
import me.jessyan.retrofiturlmanager.RetrofitUrlManager
import okhttp3.OkHttpClient
import java.security.KeyManagementException
import java.security.NoSuchAlgorithmException
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager

/**
 * 作者：fanda
 * 日期：2021/4/21 16:16
 * 描述：全局配置信息在此配置，需要将此实现类声明到 AndroidManifest 中
 */
class GlobalConfiguration : ConfigModule {

    override fun applyOptions(context: Context, builder: GlobalConfigModule.Builder) {
        // 全局配置方法
        if (!BuildConfig.LOG_DEBUG) { //Release 时, 让框架不再打印 Http 请求和响应的信息
            builder.printHttpLogLevel(RequestInterceptor.Level.NONE)
        }
        builder.baseurl(APP_DOMAIN)
                // 图片加载策略
                .imageLoaderStrategy(GlideImageLoaderStrategy())
                //这里提供一个全局处理 Http 请求和响应结果的处理类, 可以比客户端提前一步拿到服务器返回的结果, 可以做一些操作, 比如 Token 超时后, 重新获取 Token
                .globalHttpHandler(GlobalHttpHandlerImpl(context))
                //用来处理 RxJava 中发生的所有错误, RxJava 中发生的每个错误都会回调此接口
                //RxJava 必须要使用 ErrorHandleSubscriber (默认实现 Subscriber 的 onError 方法), 此监听才生效
                .responseErrorListener(ResponseErrorListenerImpl())
                .gsonConfiguration { _, gsonBuilder ->
                    gsonBuilder.setLenient()
                }
                .retrofitConfiguration { _, retrofitBuilder ->//这里可以自己自定义配置 Retrofit 的参数
                    // 比如使用 FastJson 替代 Gson
                    //retrofitBuilder.addConverterFactory(FastJsonConverterFactory.create())
                }
                .okhttpConfiguration { _, okhttpBuilder ->
                    //这里可以自己自定义配置 Okhttp 的参数
                    configOkHttp(okhttpBuilder)
                }
                .rxCacheConfiguration { _, rxCacheBuilder -> //这里可以自己自定义配置 RxCache 的参数
                    rxCacheBuilder.useExpiredDataIfLoaderNotAvailable(true);
                    //想自定义 RxCache 的缓存文件夹或者解析方式, 如改成 FastJson, 请 return rxCacheBuilder.persistence(cacheDirectory, new FastJsonSpeaker());
                    //否则请 return null;
                    null
                }
    }

    /**
     * Okhttp 的参数配置
     */
    private fun configOkHttp(okhttpBuilder: OkHttpClient.Builder) {
        okhttpBuilder.writeTimeout(10, TimeUnit.SECONDS)
        //使用一行代码监听 Retrofit／Okhttp 上传下载进度监听,以及 Glide 加载进度监听, 详细使用方法请查看 https://github.com/JessYanCoding/ProgressManager
        ProgressManager.getInstance().with(okhttpBuilder)
        //让 Retrofit 同时支持多个 BaseUrl 以及动态改变 BaseUrl, 详细使用方法请查看 https://github.com/JessYanCoding/RetrofitUrlManager
        RetrofitUrlManager.getInstance().with(okhttpBuilder)
        val manager: X509TrustManager = SslContextFactory.getX509TrustManager()
        okhttpBuilder
                .hostnameVerifier(SslContextFactory.getHostnameVerifier())
                .addInterceptor(HttpHeaderInterceptor())
        // 5.0 以下手机没有启用TLSv1.1 和 TLSv1.2 传输层安全协议协议的处理
        try {
            val sslContext = SSLContext.getInstance("TLS")
            sslContext.init(null, null, null)
            val sslSocketFactory: SSLSocketFactory = SSLSocketFactoryCompat(manager)
            okhttpBuilder.sslSocketFactory(sslSocketFactory, manager).readTimeout(15000, TimeUnit.MILLISECONDS)
                    .connectTimeout(15000, TimeUnit.MILLISECONDS)
        } catch (e: NoSuchAlgorithmException) {
            e.printStackTrace()
        } catch (e: KeyManagementException) {
            e.printStackTrace()
        }
    }

    override fun injectAppLifecycle(context: Context, lifecycles: MutableList<AppLifecycles>) {
        // APP 生命周期注入，可以有多个
        lifecycles.add(AppLifecyclesImpl())
    }

    override fun injectActivityLifecycle(context: Context, lifecycles: MutableList<Application.ActivityLifecycleCallbacks>) {
        // Activity 生命周期注入，可以有多个
        lifecycles.add(ActivityLifecycleCallbacksImpl())
    }

    override fun injectFragmentLifecycle(context: Context, lifecycles: MutableList<FragmentManager.FragmentLifecycleCallbacks>) {
        // Fragment 生命周期注入，可以有多个
        lifecycles.add(FragmentLifecycleCallbacksImpl())
    }
}